"""
行程规划视图
"""
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
from datetime import datetime, timedelta
from .models import Itinerary, DayPlan, Activity, ItineraryReminder
from .serializers import (
    ItinerarySerializer, DayPlanSerializer, ActivitySerializer,
    ItineraryReminderSerializer
)


class ItineraryViewSet(viewsets.ModelViewSet):
    """行程规划视图集"""
    serializer_class = ItinerarySerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """优化查询，使用prefetch_related减少数据库查询"""
        # 使用prefetch_related预加载关联数据（days, reminders）
        # 使用select_related优化外键查询（user）
        return Itinerary.objects.filter(user=self.request.user).select_related(
            'user'
        ).prefetch_related(
            'days', 'days__activities', 'days__activities__attraction', 'reminders'
        ).order_by('-created_at')
    
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)
    
    @action(detail=True, methods=['post'])
    def add_day(self, request, pk=None):
        """添加每日计划"""
        itinerary = self.get_object()
        day_number = request.data.get('day_number')
        date = request.data.get('date')
        
        day_plan = DayPlan.objects.create(
            itinerary=itinerary,
            day_number=day_number,
            date=date
        )
        
        serializer = DayPlanSerializer(day_plan)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    
    @action(detail=True, methods=['post'], url_path='days/(?P<day_id>[^/.]+)/activities')
    def add_activity(self, request, pk=None, day_id=None):
        """添加活动（优化查询）"""
        try:
            # 使用select_related优化查询
            day_plan = DayPlan.objects.select_related('itinerary').get(id=day_id, itinerary_id=pk)
            # 验证权限：确保行程属于当前用户
            if day_plan.itinerary.user != request.user:
                return Response(
                    {'error': '没有权限操作此行程'},
                    status=status.HTTP_403_FORBIDDEN
                )
        except DayPlan.DoesNotExist:
            return Response({'error': '每日计划不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        activity_data = request.data.copy()
        activity_data['day_plan'] = day_plan.id
        
        serializer = ActivitySerializer(data=activity_data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=True, methods=['put', 'patch'], url_path='days/(?P<day_id>[^/.]+)/activities/(?P<activity_id>[^/.]+)')
    def update_activity(self, request, pk=None, day_id=None, activity_id=None):
        """更新活动（优化查询）"""
        try:
            # 使用select_related优化查询
            day_plan = DayPlan.objects.select_related('itinerary').get(id=day_id, itinerary_id=pk)
            # 验证权限：确保行程属于当前用户
            if day_plan.itinerary.user != request.user:
                return Response(
                    {'error': '没有权限操作此行程'},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            activity = Activity.objects.select_related('day_plan', 'day_plan__itinerary').get(
                id=activity_id,
                day_plan_id=day_id
            )
        except DayPlan.DoesNotExist:
            return Response({'error': '每日计划不存在'}, status=status.HTTP_404_NOT_FOUND)
        except Activity.DoesNotExist:
            return Response({'error': '活动不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        activity_data = request.data.copy()
        # 不允许修改day_plan
        if 'day_plan' in activity_data:
            del activity_data['day_plan']
        
        serializer = ActivitySerializer(activity, data=activity_data, partial=request.method == 'PATCH')
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=True, methods=['delete'], url_path='days/(?P<day_id>[^/.]+)/activities/(?P<activity_id>[^/.]+)')
    def delete_activity(self, request, pk=None, day_id=None, activity_id=None):
        """删除活动（优化查询）"""
        try:
            # 使用select_related优化查询
            day_plan = DayPlan.objects.select_related('itinerary').get(id=day_id, itinerary_id=pk)
            # 验证权限：确保行程属于当前用户
            if day_plan.itinerary.user != request.user:
                return Response(
                    {'error': '没有权限操作此行程'},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            activity = Activity.objects.select_related('day_plan', 'day_plan__itinerary').get(
                id=activity_id,
                day_plan_id=day_id
            )
        except DayPlan.DoesNotExist:
            return Response({'error': '每日计划不存在'}, status=status.HTTP_404_NOT_FOUND)
        except Activity.DoesNotExist:
            return Response({'error': '活动不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        activity.delete()
        return Response({'message': '活动已删除'}, status=status.HTTP_204_NO_CONTENT)
    
    @action(detail=True, methods=['post'])
    def create_reminder(self, request, pk=None):
        """创建行程提醒"""
        itinerary = self.get_object()
        reminder_type = request.data.get('reminder_type', 'day')
        reminder_time_str = request.data.get('reminder_time')
        message = request.data.get('message', '')
        is_enabled = request.data.get('is_enabled', True)
        
        if not reminder_time_str:
            return Response(
                {'error': '提醒时间不能为空'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            reminder_time = datetime.fromisoformat(reminder_time_str.replace('Z', '+00:00'))
            if reminder_time.tzinfo is None:
                reminder_time = timezone.make_aware(reminder_time)
        except (ValueError, AttributeError):
            return Response(
                {'error': '提醒时间格式错误'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 如果没有提供消息，生成默认消息
        if not message:
            if reminder_type == 'start':
                message = f'您的行程"{itinerary.title}"即将开始！'
            elif reminder_type == 'day':
                message = f'今天是您行程"{itinerary.title}"的第{itinerary.start_date}天，祝您旅途愉快！'
            else:
                message = f'您有行程活动提醒：{itinerary.title}'
        
        reminder = ItineraryReminder.objects.create(
            itinerary=itinerary,
            reminder_type=reminder_type,
            reminder_time=reminder_time,
            message=message,
            is_enabled=is_enabled
        )
        
        serializer = ItineraryReminderSerializer(reminder)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    
    @action(detail=True, methods=['get'])
    def reminders(self, request, pk=None):
        """获取行程的所有提醒（优化查询）"""
        itinerary = self.get_object()
        # 使用select_related优化查询
        reminders = ItineraryReminder.objects.filter(
            itinerary=itinerary,
            is_enabled=True
        ).select_related('itinerary').order_by('reminder_time')
        
        serializer = ItineraryReminderSerializer(reminders, many=True)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def upcoming_reminders(self, request):
        """获取即将到来的提醒（未来24小时内，优化查询），并可选择写入服务端通知"""
        now = timezone.now()
        tomorrow = now + timedelta(days=1)
        
        # 使用select_related优化查询，减少数据库查询次数
        reminders = ItineraryReminder.objects.filter(
            itinerary__user=request.user,
            is_enabled=True,
            status='pending',
            reminder_time__gte=now,
            reminder_time__lte=tomorrow
        ).select_related('itinerary', 'itinerary__user').order_by('reminder_time')
        
        serializer = ItineraryReminderSerializer(reminders, many=True)

        # 可选：写入服务端通知，避免重复写入（10分钟内重复提醒不再写入）
        create_notifications = request.query_params.get('create_notifications') in ('1', 'true', 'True')
        if create_notifications:
            try:
                from apps.notifications.models import Notification
                cutoff = now - timedelta(minutes=10)
                for r in reminders:
                    exists = Notification.objects.filter(
                        user=request.user,
                        type='reminder',
                        created_at__gte=cutoff,
                        body__icontains=r.message[:50] if r.message else ''
                    ).exists()
                    if not exists:
                        Notification.objects.create(
                            user=request.user,
                            title='行程提醒',
                            body=r.message or f'您的行程"{r.itinerary.title}"有新的提醒',
                            type='reminder',
                            read=False
                        )
            except Exception:
                pass

        return Response({
            'count': len(serializer.data),
            'results': serializer.data
        })


class ItineraryReminderViewSet(viewsets.ModelViewSet):
    """行程提醒视图集"""
    serializer_class = ItineraryReminderSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """优化查询，使用select_related减少数据库查询"""
        return ItineraryReminder.objects.filter(
            itinerary__user=self.request.user
        ).select_related('itinerary', 'itinerary__user').order_by('-reminder_time')
    
    @action(detail=True, methods=['post'])
    def toggle(self, request, pk=None):
        """启用/禁用提醒"""
        reminder = self.get_object()
        reminder.is_enabled = not reminder.is_enabled
        reminder.save()
        
        serializer = self.get_serializer(reminder)
        return Response(serializer.data)
    
    @action(detail=True, methods=['post'])
    def mark_sent(self, request, pk=None):
        """标记提醒为已发送"""
        reminder = self.get_object()
        reminder.status = 'sent'
        reminder.sent_at = timezone.now()
        reminder.save()
        
        serializer = self.get_serializer(reminder)
        return Response(serializer.data)

